#ifndef XN_CAN_H
#define XN_CAN_H
#include <net/if.h>
#include "libsocketcan.h"
#include <linux/can.h>
#include <linux/can/raw.h>

// socket can 依赖 libsocketcan.so
#ifndef PF_CAN
#define PF_CAN 29
#endif

#ifndef AF_CAN
#define AF_CAN PF_CAN
#endif

typedef struct _SCanIDBC
{
	unsigned int SA : 8;    // 源地址
	unsigned int DA : 8;    // 目标地址
	unsigned int PF : 8;    // 命令代码
	unsigned int DP : 1;    // 固定为0
	unsigned int R :  1;    // 固定为0
	unsigned int Prio : 3;  // 优先级
}SCanIDBC;

typedef struct _SCanIBXK
{
	unsigned int NA : 3;	// 备用
	unsigned int CNT :  1;	// CNT
	unsigned int SA : 8;    // 源地址 
	unsigned int DA : 8;    // 目标地址
	unsigned int PF : 8;    // 命令代码 
	unsigned int PTP : 1;	// 固定为1
}SCcanIDXK;

typedef struct _SCanMutiFrame 
{ 
	unsigned int can_id;
	unsigned char can_dlc;
	unsigned char data[8];
}SCanMutiFrame;

class CXnCan
{
public:
	CXnCan();
	~CXnCan();

public:
	 /*
	 pDeviceName := /dev/canX (unix) | CAN1 CAN2 (Windows) 
	 iSpeed      := 5K 10K 20K 50K 100K 125K 250K 500K 800K 1000K  
	 */
	 int openDevice(const char *pDeviceName, int iSpeed = 250 * 1000);
	 int closeDevice();    
	 int readFrame(unsigned int& uiCanId, unsigned char* pBuf, int iTimeout = -1);
	 int readMultiFrame(unsigned char* pBuf, int iFrameNum, int iTimeout = -1);	
	 int writeFrame(unsigned int uiCanId, unsigned char* pBuf, unsigned char uaLen);

private:
	int select(int iTimeout = 500);

private:
	bool m_bOpenOK;

	char m_aCanName[64];
	int m_fdSocketCan;
};

#endif